const express = require('express');
const { Op } = require('sequelize');
const { Activity, User, ActivityParticipant, CheckIn, Badge } = require('../models');
const { authenticateToken, optionalAuth } = require('../middleware/auth');
const { validateActivityCreation, validateCheckIn, validatePagination } = require('../middleware/validation');
const recommendationService = require('../services/recommendationService');
const blockchainService = require('../services/blockchainService');
const { sequelize } = require('../models');

const router = express.Router();

// 获取活动列表
router.get('/', validatePagination, async (req, res) => {
  try {
    const page = parseInt(req.query.page) || 1;
    const limit = parseInt(req.query.limit) || 50;
    const offset = (page - 1) * limit;
    const { category, status, search } = req.query;

    let whereConditions = {};
    let includeConditions = [];

    // 状态筛选逻辑
    if (status) {
      switch (status) {
        case 'my':
          // 我创建的活动
          if (req.user) {
            whereConditions.created_by = req.user.id;
          } else {
            // 未登录用户返回空结果
            return res.json({
              activities: [],
              pagination: { page, limit, total: 0, totalPages: 0 }
            });
          }
          break;
        
        case 'joined':
          // 我参与的活动
          if (req.user) {
            includeConditions.push({
              model: ActivityParticipant,
              as: 'participants',
              where: { user_id: req.user.id },
              required: true
            });
          } else {
            return res.json({
              activities: [],
              pagination: { page, limit, total: 0, totalPages: 0 }
            });
          }
          break;
        
        case 'ongoing':
          // 正在进行的活动
          const now = new Date();
          whereConditions.start_time = { [Op.lte]: now };
          whereConditions.end_time = { [Op.gte]: now };
          whereConditions.status = { [Op.in]: ['published', 'ongoing'] };
          break;
        
        case 'upcoming':
          // 即将开始的活动
          const currentTime = new Date();
          whereConditions.start_time = { [Op.gt]: currentTime };
          whereConditions.status = { [Op.in]: ['published'] };
          break;
        
        case 'finished':
          // 已结束的活动
          const nowTime = new Date();
          whereConditions.end_time = { [Op.lt]: nowTime };
          break;
        
        case 'available':
          // 可参与的活动（默认状态）
          whereConditions.status = { [Op.in]: ['published', 'ongoing'] };
          break;
        
        default:
          // 直接使用状态值
          whereConditions.status = status;
          break;
      }
    } else {
      // 默认显示可参与的活动
      whereConditions.status = { [Op.in]: ['published', 'ongoing'] };
    }

    // 分类筛选
    if (category) {
      whereConditions.category_id = category;
    }

    // 搜索
    if (search) {
      whereConditions[Op.or] = [
        { title: { [Op.like]: `%${search}%` } },
        { description: { [Op.like]: `%${search}%` } },
        { location: { [Op.like]: `%${search}%` } }
      ];
    }

    // 构建查询配置
    const queryConfig = {
      where: whereConditions,
      include: [
        {
          model: User,
          as: 'creator',
          attributes: ['id', 'username', 'avatar_url']
        },
        ...includeConditions
      ],
      order: [['start_time', 'ASC']],
      limit,
      offset
    };

    const { count, rows: activities } = await Activity.findAndCountAll(queryConfig);

    // 获取当前用户参与状态
    if (req.user) {
      for (const activity of activities) {
        const participation = await ActivityParticipant.findOne({
          where: {
            activity_id: activity.id,
            user_id: req.user.id
          }
        });
        
        activity.setDataValue('userParticipation', participation ? participation.status : null);
      }
    }

    res.json({
      activities,
      pagination: {
        page,
        limit,
        total: count,
        totalPages: Math.ceil(count / limit)
      }
    });
  } catch (error) {
    console.error('获取活动列表失败:', error);
    res.status(500).json({
      error: '获取活动列表失败',
      details: error.message
    });
  }
});

// 获取推荐活动
router.get('/recommendations', authenticateToken, async (req, res) => {
  try {
    const limit = parseInt(req.query.limit) || 10;
    const recommendations = await recommendationService.getUserRecommendations(req.user.id, limit);

    res.json({
      recommendations
    });
  } catch (error) {
    console.error('获取推荐活动失败:', error);
    res.status(500).json({
      error: '获取推荐活动失败'
    });
  }
});

// 获取最近的活动列表（用于管理员仪表盘）
router.get('/recent', async (req, res) => {
  try {
    const activities = await Activity.findAll({
      order: [['createdAt', 'DESC']],
      limit: 5,
      include: [
        {
          model: User,
          as: 'creator',
          attributes: ['id', 'username', 'avatar_url']
        }
      ]
    });

    res.json({
      activities
    });
  } catch (error) {
    console.error('获取最近活动失败:', error);
    res.status(500).json({
      error: '获取最近活动失败'
    });
  }
});

// 获取单个活动详情
router.get('/:id', optionalAuth, async (req, res) => {
  try {
    const activity = await Activity.findByPk(req.params.id, {
      include: [
        {
          model: User,
          as: 'creator',
          attributes: ['id', 'username', 'avatar_url']
        },
        {
          model: ActivityParticipant,
          as: 'participants',
          include: [
            {
              model: User,
              as: 'user',
              attributes: ['id', 'username', 'avatar_url']
            }
          ]
        }
      ]
    });

    if (!activity) {
      return res.status(404).json({
        error: '活动不存在'
      });
    }

    // 检查用户是否已参与
    let userParticipation = null;
    if (req.user) {
      userParticipation = await ActivityParticipant.findOne({
        where: {
          user_id: req.user.id,
          activity_id: activity.id
        }
      });
    }

    res.json({
      activity: {
        ...activity.toJSON(),
        userParticipation
      }
    });
  } catch (error) {
    console.error('获取活动详情失败:', error);
    res.status(500).json({
      error: '获取活动详情失败'
    });
  }
});

// 创建活动
router.post('/', authenticateToken, validateActivityCreation, async (req, res) => {
  try {
    const {
      title,
      description,
      location,
      start_time,
      end_time,
      max_participants,
      category_id,
      tags,
      requirements,
      latitude,
      longitude,
      image_url
    } = req.body;

    const activity = await Activity.create({
      title,
      description,
      location,
      start_time,
      end_time,
      max_participants,
      category_id,
      tags,
      requirements,
      latitude,
      longitude,
      image_url,
      created_by: req.user.id,
      status: 'published'
    });

    // 获取完整的活动信息
    const fullActivity = await Activity.findByPk(activity.id, {
      include: [
        {
          model: User,
          as: 'creator',
          attributes: ['id', 'username', 'avatar_url']
        }
      ]
    });

    // 通过Socket.IO广播新活动
    const io = req.app.get('io');
    io.emit('new_activity', fullActivity);

    res.status(201).json({
      message: '活动创建成功',
      activity: fullActivity
    });
  } catch (error) {
    console.error('创建活动失败:', error);
    res.status(500).json({
      error: '创建活动失败',
      details: error.message
    });
  }
});

// 更新活动
router.put('/:id', authenticateToken, async (req, res) => {
  try {
    const activity = await Activity.findByPk(req.params.id);

    if (!activity) {
      return res.status(404).json({
        error: '活动不存在'
      });
    }

    // 检查权限
    if (activity.created_by !== req.user.id) {
      return res.status(403).json({
        error: '无权限修改此活动'
      });
    }

    const {
      title,
      description,
      location,
      start_time,
      end_time,
      max_participants,
      category_id,
      tags,
      requirements,
      latitude,
      longitude,
      image_url,
      status
    } = req.body;

    await activity.update({
      title: title || activity.title,
      description: description !== undefined ? description : activity.description,
      location: location !== undefined ? location : activity.location,
      start_time: start_time || activity.start_time,
      end_time: end_time || activity.end_time,
      max_participants: max_participants !== undefined ? max_participants : activity.max_participants,
      category_id: category_id !== undefined ? category_id : activity.category_id,
      tags: tags !== undefined ? tags : activity.tags,
      requirements: requirements !== undefined ? requirements : activity.requirements,
      latitude: latitude !== undefined ? latitude : activity.latitude,
      longitude: longitude !== undefined ? longitude : activity.longitude,
      image_url: image_url !== undefined ? image_url : activity.image_url,
      status: status || activity.status
    });

    res.json({
      message: '活动更新成功',
      activity
    });
  } catch (error) {
    console.error('更新活动失败:', error);
    res.status(500).json({
      error: '更新活动失败'
    });
  }
});

// 删除活动
router.delete('/:id', authenticateToken, async (req, res) => {
  try {
    const activity = await Activity.findByPk(req.params.id);

    if (!activity) {
      return res.status(404).json({
        error: '活动不存在'
      });
    }

    // 检查权限
    if (activity.created_by !== req.user.id) {
      return res.status(403).json({
        error: '无权限删除此活动'
      });
    }

    // 检查是否有用户已参与
    const participantCount = await ActivityParticipant.count({
      where: { activity_id: activity.id }
    });

    if (participantCount > 0) {
      return res.status(400).json({
        error: '已有用户参与的活动不能删除，只能取消'
      });
    }

    await activity.destroy();

    res.json({
      message: '活动删除成功'
    });
  } catch (error) {
    console.error('删除活动失败:', error);
    res.status(500).json({
      error: '删除活动失败'
    });
  }
});

// 参与活动
router.post('/:id/join', authenticateToken, async (req, res) => {
  const transaction = await sequelize.transaction();
  
  try {
    const activity = await Activity.findByPk(req.params.id, { transaction });

    if (!activity) {
      await transaction.rollback();
      return res.status(404).json({
        error: '活动不存在'
      });
    }

    // 检查活动状态
    if (activity.status !== 'published') {
      await transaction.rollback();
      return res.status(400).json({
        error: '活动未开放报名'
      });
    }

    // 检查活动时间状态
    const now = new Date();
    const startTime = new Date(activity.start_time);
    const endTime = new Date(activity.end_time);
    
    // 活动已结束，不能参与
    if (now > endTime) {
      await transaction.rollback();
      return res.status(400).json({
        error: '活动已结束，无法报名'
      });
    }
    
    // 活动开始超过30分钟后，不允许新的参与（可选限制）
    const maxLateJoinMinutes = 30;
    const lateJoinCutoff = new Date(startTime.getTime() + maxLateJoinMinutes * 60 * 1000);
    if (now > lateJoinCutoff) {
      await transaction.rollback();
      return res.status(400).json({
        error: `活动开始超过${maxLateJoinMinutes}分钟后无法报名`
      });
    }

    // 检查是否已参与
    const existingParticipation = await ActivityParticipant.findOne({
      where: {
        user_id: req.user.id,
        activity_id: activity.id
      },
      transaction
    });

    if (existingParticipation) {
      await transaction.rollback();
      return res.status(400).json({
        error: '您已参与此活动'
      });
    }

    // 检查人数限制
    if (activity.max_participants && activity.current_participants >= activity.max_participants) {
      await transaction.rollback();
      return res.status(400).json({
        error: '活动人数已满'
      });
    }

    // 创建参与记录
    await ActivityParticipant.create({
      user_id: req.user.id,
      activity_id: activity.id,
      status: 'registered'
    }, { transaction });

    // 更新参与人数
    await activity.increment('current_participants', { transaction });

    // 提交事务
    await transaction.commit();

    // 异步执行可选操作（不影响主要功能）
    setImmediate(async () => {
      try {
        // 更新用户画像
        await recommendationService.updateUserProfile(req.user.id, activity.id, 'join');
      } catch (error) {
        console.error('更新用户画像失败:', error);
      }

      try {
        // 通过Socket.IO通知活动创建者
        const io = req.app.get('io');
        if (io) {
          io.to(`user_${activity.created_by}`).emit('activity_joined', {
            activityId: activity.id,
            userId: req.user.id,
            username: req.user.username
          });
        }
      } catch (error) {
        console.error('Socket.IO通知失败:', error);
      }
    });

    res.json({
      message: '参与活动成功'
    });
  } catch (error) {
    await transaction.rollback();
    console.error('参与活动失败:', error);
    res.status(500).json({
      error: '参与活动失败',
      details: process.env.NODE_ENV === 'development' ? error.message : undefined
    });
  }
});

// 取消参与活动
router.post('/:id/leave', authenticateToken, async (req, res) => {
  const transaction = await sequelize.transaction();
  
  try {
    const participation = await ActivityParticipant.findOne({
      where: {
        user_id: req.user.id,
        activity_id: req.params.id
      },
      transaction
    });

    if (!participation) {
      await transaction.rollback();
      return res.status(404).json({
        error: '您未参与此活动'
      });
    }

    const activity = await Activity.findByPk(req.params.id, { transaction });

    // 检查是否可以取消
    if (participation.status === 'attended') {
      await transaction.rollback();
      return res.status(400).json({
        error: '已签到的活动无法取消参与'
      });
    }

    // 更新参与状态
    await participation.update({ status: 'cancelled' }, { transaction });

    // 减少参与人数
    if (activity && activity.current_participants > 0) {
      await activity.decrement('current_participants', { transaction });
    }

    // 提交事务
    await transaction.commit();

    res.json({
      message: '取消参与成功'
    });
  } catch (error) {
    await transaction.rollback();
    console.error('取消参与失败:', error);
    res.status(500).json({
      error: '取消参与失败',
      details: process.env.NODE_ENV === 'development' ? error.message : undefined
    });
  }
});

// 活动签到
router.post('/:id/checkin', authenticateToken, validateCheckIn, async (req, res) => {
  try {
    const { latitude, longitude, verification_code } = req.body;
    const activityId = req.params.id;

    const activity = await Activity.findByPk(activityId);
    if (!activity) {
      return res.status(404).json({
        error: '活动不存在'
      });
    }

    // 检查是否已参与活动
    const participation = await ActivityParticipant.findOne({
      where: {
        user_id: req.user.id,
        activity_id: activityId
      }
    });

    if (!participation) {
      return res.status(400).json({
        error: '您未参与此活动'
      });
    }

    // 检查是否已签到
    const existingCheckIn = await CheckIn.findOne({
      where: {
        user_id: req.user.id,
        activity_id: activityId
      }
    });

    if (existingCheckIn) {
      return res.status(400).json({
        error: '您已签到过此活动'
      });
    }

    // 检查签到时间
    const now = new Date();
    const startTime = new Date(activity.start_time);
    const endTime = new Date(activity.end_time);

    if (now < startTime || now > endTime) {
      return res.status(400).json({
        error: '不在签到时间范围内'
      });
    }

    // 地理位置验证（如果提供了坐标）
    let locationVerified = false;
    if (latitude && longitude && activity.latitude && activity.longitude) {
      const distance = calculateDistance(
        latitude, longitude,
        activity.latitude, activity.longitude
      );
      locationVerified = distance <= 0.1; // 100米内
    }

    // 创建签到记录
    const checkIn = await CheckIn.create({
      user_id: req.user.id,
      activity_id: activityId,
      latitude,
      longitude,
      location_verified: locationVerified,
      verification_code
    });

    // 更新参与状态
    await participation.update({
      status: 'attended',
      attended_at: new Date()
    });

    // 更新用户画像
    await recommendationService.updateUserProfile(req.user.id, activityId, 'checkin');

    // 生成NFT徽章
    try {
      const badgeData = {
        userId: req.user.id,
        name: `${activity.title} 参与徽章`,
        description: `参与了 ${activity.title} 活动的纪念徽章`,
        imageUrl: blockchainService.generateBadgeImage(activity),
        rarity: 'common',
        attributes: [
          { trait_type: 'Activity', value: activity.title },
          { trait_type: 'Date', value: new Date().toISOString().split('T')[0] },
          { trait_type: 'Location', value: activity.location || 'Unknown' }
        ]
      };

      // 异步铸造NFT，不阻塞签到流程
      blockchainService.mintNFTBadge(req.user.wallet_address, activityId, badgeData)
        .then(result => {
          console.log('NFT徽章铸造成功:', result);
          
          // 通过Socket.IO通知用户
          const io = req.app.get('io');
          io.to(`user_${req.user.id}`).emit('badge_minted', {
            badge: result.badge,
            transactionHash: result.transactionHash
          });
        })
        .catch(error => {
          console.error('NFT徽章铸造失败:', error);
        });

    } catch (error) {
      console.error('启动NFT铸造失败:', error);
    }

    res.json({
      message: '签到成功',
      checkIn,
      badgeMessage: '正在为您生成NFT徽章，请稍候...'
    });
  } catch (error) {
    console.error('签到失败:', error);
    res.status(500).json({
      error: '签到失败'
    });
  }
});

// 获取活动参与者列表
router.get('/:id/participants', async (req, res) => {
  try {
    const participants = await ActivityParticipant.findAll({
      where: {
        activity_id: req.params.id,
        status: { [Op.in]: ['registered', 'attended'] }
      },
      include: [
        {
          model: User,
          as: 'user',
          attributes: ['id', 'username', 'avatar_url']
        }
      ],
      order: [['registered_at', 'ASC']]
    });

    res.json({
      participants
    });
  } catch (error) {
    console.error('获取参与者列表失败:', error);
    res.status(500).json({
      error: '获取参与者列表失败'
    });
  }
});

// 计算两点间距离（公里）
function calculateDistance(lat1, lon1, lat2, lon2) {
  const R = 6371; // 地球半径（公里）
  const dLat = (lat2 - lat1) * Math.PI / 180;
  const dLon = (lon2 - lon1) * Math.PI / 180;
  const a = Math.sin(dLat/2) * Math.sin(dLat/2) +
    Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
    Math.sin(dLon/2) * Math.sin(dLon/2);
  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
  return R * c;
}

module.exports = router; 